﻿using Deployment.Data.Deploy.Steps;
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;


namespace Deployment.Data.Deploy
{
    [XmlRoot("Deployment")]
    [Serializable()]
    public class DeploymentFile : NotifyPropertyChanged
    {
        private string _version;
        private ObservableSortedList<Step> _steps = new ObservableSortedList<Step>(4, new StepComparer());

        [XmlAttribute]
        public string Version
        {
            get { return _version; }
            set
            {
                if (string.IsNullOrEmpty(value))
                    throw new ArgumentException("Version cannot be null or empty.");
                if (_version != value)
                {
                    _version = value;
                    OnPropertyChanged("Version");
                }
            }
        }

        public ObservableSortedList<Step> Steps
        {
            get { return _steps; }
        }

        public bool AddStep(Step newStep)
        {
            if (newStep == null)
                throw new ArgumentNullException("newStep");
            Step duplicateStep = null;
            foreach (Step step in _steps)
            {
                if (step.Sequence == newStep.Sequence)
                {
                    duplicateStep = step;
                    break;
                }
            }
            if (duplicateStep != null)
            {
                DuplicateStepDialog dialog = new DuplicateStepDialog(duplicateStep, newStep);
                bool? result = dialog.ShowDialog();
                if (result.HasValue && result.Value == true)
                {
                    reOrderExistingSteps(newStep, dialog.reOrder);
                }
                else
                {
                    return false;
                }
            }
            _steps.Add(newStep);
            return true;
        }

        public void SaveToFile(string fileName)
        {
            if (string.IsNullOrEmpty(fileName))
                throw new ArgumentException("fileName cannot be null or empty.");
            using (StreamWriter sw = new StreamWriter(fileName, false))
            {
                XmlSerializer xml = new XmlSerializer(typeof(DeploymentFile));
                xml.Serialize(sw, this);
                sw.Close();
            }
        }

        public static DeploymentFile LoadFromFile(string fileName)
        {
            if (string.IsNullOrEmpty(fileName))
                throw new ArgumentException("fileName cannot be null or empty.");
            if (!File.Exists(fileName))
                throw new FileNotFoundException("Unable to locate input file", fileName);
            DeploymentFile obj;
            FileStream inStream = new FileStream(fileName, FileMode.Open);
            XmlSerializer xml = new XmlSerializer(typeof(DeploymentFile));

            obj = (DeploymentFile)xml.Deserialize(inStream);
            inStream.Close();
            return obj;
        }

        private void reOrderExistingSteps(Step newStep, int ReorderType)
        {
            if (ReorderType == 1)
                newStep.Sequence++;
            foreach (Step step in _steps)
            {
                if (step.Sequence >= newStep.Sequence)
                    step.Sequence++;
            }
        }

        private class StepComparer : IComparer<Steps.Step>
        {

            public int Compare(Steps.Step x, Steps.Step y)
            {
                if (x == null && y == null)
                    return 0;
                if (x == null && y != null)
                    return -1;
                if (x != null && y == null)
                    return 1;

                return x.Sequence - y.Sequence;
            }
        }

    }
}
